package cn.ipanel.bigdata.boot.date

import java.text.SimpleDateFormat

/**
 * Author: lzz
 * Date: 2021/11/19 15:20
 */
class Date(sTime: Long, eTime: Long) extends Serializable {

  import Date._

  lazy final val STime: Time = Time(sTime)
  lazy final val ETime: Time = Time(eTime)
  lazy final val diff: Long = eTime - sTime

  def prev(n: Int = 1): Date = Date(sTime - diff, sTime)
  def next(n: Int = 1): Date = Date(eTime, eTime + diff)

  def lenDays: Int = ((eTime + 1 - sTime) / DAY_TIME).toInt
  def todayIn: Boolean = {
    val time = System.currentTimeMillis()
    if (time >= sTime && time <= eTime) true
    else false
  }

  def asDay: Day = STime.asDay
  def asWeek: Week = STime.asWeek
  def asMonth: Month = STime.asMonth
  def asYear: Year = STime.asYear
  def asQuarter: Quarter = STime.asQuarter
  def asHour: Hour = STime.asHour
  def asMinute: Minute = STime.asMinute

  def asEDay: Day = ETime.asDay
  def asEWeek: Week = ETime.asWeek
  def asEMonth: Month = ETime.asMonth
  def asEYear: Year = ETime.asYear
  def asEQuarter: Quarter = ETime.asQuarter
  def asEHour: Hour = ETime.asHour
  def asEMinute: Minute = ETime.asMinute

  def toDate: Int = STime.toDate
  def toSimpleDate: Int = STime.toSimpleDate
  def toSimpleMonth: Int = STime.toSimpleMonth
  def toSimpleHour: Long = STime.toSimpleHour
  def toTime: String = STime.to()
  def toSimpleMinute: Long = STime.toSimpleMinute
  def toFullHour: Long = STime.toFullHour
  def toWeekDay: Int = STime.asWeek.toDate
  def toYear: Int = STime.toYear
  def toMonth: Int = STime.toMonth
  def toYearMonth: Int = STime.toYearMonth
  def toQuarter: Int = STime.toQuarter
  def toYearQuarter: Int = STime.toYearQuarter
  def toHour: Int = STime.toHour
  def toDayHour: Int = STime.toDayHour
  def toMinute: Int = STime.toMinute
  def toDayMinute: Int = STime.toDayMinute

  def toEDate: Int = ETime.toDate
  def toEWeekDay: Int = ETime.asWeek.toDate
  def toEYear: Int = ETime.toYear
  def toEMonth: Int = ETime.toMonth
  def toEYearMonth: Int = ETime.toYearMonth
  def toEQuarter: Int = ETime.toQuarter
  def toEYearQuarter: Int = ETime.toYearQuarter
  def toEHour: Int = ETime.toHour
  def toEDayHour: Int = ETime.toDayHour
  def toEMinute: Int = ETime.toMinute
  def toEDayMinute: Int = ETime.toDayMinute

  override def toString: String = s"Period(${STime.toYYYYMMddHHmmss} To ${ETime.toYYYYMMddHHmmss})"
  override def equals(obj: Any): Boolean = {
    if (obj == null || !obj.isInstanceOf[Date]) false
    else {
      val p = obj.asInstanceOf[Date]
      if (p.STime.equals(STime) && p.ETime.equals(ETime)) true
      else false
    }
  }
  def printFormat(format: String = "yyyy-MM-dd HH:mm:ss"): String = {
    new SimpleDateFormat(format).format(new java.util.Date(sTime))
  }

}

object Date {

  val SECOND_MILLISECOND: Long = 1000
  val DAY_HOUR: Long = 24
  val DAY_MINUTE: Long = DAY_HOUR * 60
  val DAY_SECONDS: Long = DAY_MINUTE * 60
  val DAY_TIME: Long = DAY_SECONDS * SECOND_MILLISECOND
  val HOUR_TIME: Long = 3600 * SECOND_MILLISECOND
  val MINUTE_TIME: Long = 60 * SECOND_MILLISECOND
  val WEEK_DAY_TIME: Long = DAY_TIME * 7

  val JANUARY: Int = 0
  val FEBRUARY: Int = 1
  val MARCH: Int = 2
  val APRIL: Int = 3
  val MAY: Int = 4
  val JUNE: Int = 5
  val JULY: Int = 6
  val AUGUST: Int = 7
  val SEPTEMBER: Int = 8
  val OCTOBER: Int = 9
  val NOVEMBER: Int = 10
  val DECEMBER: Int = 11

  val Q1: Int = 1
  val Q2: Int = 2
  val Q3: Int = 3
  val Q4: Int = 4

  val Q_MONTH: Seq[Seq[Int]] = Seq(Seq(JANUARY, FEBRUARY, MARCH),
                                   Seq(APRIL, MAY, JUNE),
                                   Seq(JULY, AUGUST, SEPTEMBER),
                                   Seq(OCTOBER, NOVEMBER, DECEMBER))

  def asDay(yyyyMMdd: String): Day = Day(yyyyMMdd)
  def asWeek(yyyyMMdd: String): Week = Week(yyyyMMdd)
  def asMonth(yyyyMMdd: String): Month = Month(yyyyMMdd)
  def asYear(yyyyMMdd: String): Year = Year(yyyyMMdd)
  def asQuarter(yyyyMMdd: String): Quarter = Quarter(yyyyMMdd)

  def asToday: Day = Day(System.currentTimeMillis())
  def asYesterday: Day = Day(System.currentTimeMillis() - DAY_TIME)
  def asTomorrow: Day = Day(System.currentTimeMillis() + DAY_TIME)
  def asWeek: Week = Week(System.currentTimeMillis())
  def asMonth: Month = Month(System.currentTimeMillis())
  def asYear: Year = Year(System.currentTimeMillis())
  def asQuarter: Quarter = Quarter(System.currentTimeMillis())
  def asMinute: Minute = Minute(System.currentTimeMillis())
  def asHour: Hour = Hour(System.currentTimeMillis())

  def isValid(p: Date): Boolean = {
    if (p == null) false
    else if (p.STime.time <= 0 || p.ETime.time <= 0) false
    else if (p.STime.time > p.ETime.time) false
    else true
  }

  def min(d1: Day, d2: Day): Day = if (d1.et > d2.et) d2 else d1
  def max(d1: Day, d2: Day): Day = if (d1.et > d2.et) d1 else d2

  def apply(st: Long, et: Long): Date = new Date(st, et)
}